#include "stdafx.h"
#include "ServerClientManager.h"
#include "..\Common\CommonUtil.h"



client_manager::client_manager(void)
: m_bRepeating(false), m_bLock(false) {
	InitializeCriticalSection(&m_CriticalSection);	
}

client_manager::~client_manager(void) {
	DeleteCriticalSection(&m_CriticalSection);
}



void client_manager::StartRepeat(void) {
	EnterCriticalSection(&m_CriticalSection);
	// Leave called by EndRepate.

	assert(m_bRepeating == false);
	m_bRepeating = true;
	m_Repeator = m_ClientInfoList.begin();
}

void client_manager::EndRepeat(void) {
	assert(m_bRepeating == true);	

	m_bRepeating = false;
	LeaveCriticalSection(&m_CriticalSection);
	// Enter called by Start Repeat
}

void client_manager::NextRepeat(void) {
	assert(m_bRepeating == true);
	assert(m_Repeator != m_ClientInfoList.end());

	++m_Repeator;
}

client_manager::client_save_structure* client_manager::Repeat(void) {		
	assert(m_bRepeating == true);

	if(m_Repeator != m_ClientInfoList.end())
		return &(*m_Repeator);
	else
		return NULL;
}


int	 client_manager::GetClientCount(void) {	
	cs_auto cs(&m_CriticalSection);

	return m_ClientInfoList.size();
}

bool client_manager::NewClient(network* ServiceNetwork, network* BroadcasterNetwork, unsigned int ThreadNumber) {
	cs_auto cs(&m_CriticalSection);

	client_manager::client_save_structure NewClientData;
	NewClientData.ServiceNetwork		= ServiceNetwork;
	NewClientData.BroadcastNetwork		= BroadcasterNetwork;
	NewClientData.ClientCode			= this->GenerateClientCode();
	NewClientData.ServiceThreadNumber	= ThreadNumber;
	NewClientData.UdpPort				= UDP_NOT_READY; // other path update. 
	NewClientData.UdpConnectCount		= 0;

	NewClientData.LastUdpRecvCount			= 0;
	NewClientData.LastUdpRecvCountUpdate	= 0;
	NewClientData.CurrentUdpRecvCount		= 0;

	m_ClientInfoList.push_back(NewClientData);

	return true;
}

bool client_manager::DeleteClient(unsigned int ClientCode) {
	cs_auto cs(&m_CriticalSection);

	bool Result = false;
		
	for(StartRepeat(); Repeat() != NULL;	NextRepeat()) 
		if(Repeat()->ClientCode == ClientCode)
			break;

	if(Repeat() != NULL) {		
		m_ClientInfoList.erase(m_Repeator);
		Result = true;
	}
	EndRepeat();

	return Result;	
}
	

void client_manager::Lock(void) {	
	EnterCriticalSection(&m_CriticalSection);

	assert(m_bLock == false); 
	m_bLock = true;
}

client_manager::client_save_structure* client_manager::SearchClient(network* PtrNetwork) {
	assert(m_bLock == true);
	for(clinet_info_list::iterator it = m_ClientInfoList.begin(); 
			it != m_ClientInfoList.end(); 		++it)
			if( (it->ServiceNetwork == PtrNetwork) || (it->BroadcastNetwork == PtrNetwork) )
				return &(*it);

	return NULL;	
}

client_manager::client_save_structure* client_manager::SearchClient(unsigned int ClientCode) {
	assert(m_bLock == true);
	for(clinet_info_list::iterator it = m_ClientInfoList.begin(); 
			it != m_ClientInfoList.end(); 		++it)
		if(it->ClientCode == ClientCode)
			return &(*it);
	
	return NULL;
}

void client_manager::UnLock(void) {
	assert(m_bLock == true);

	m_bLock = false;
	LeaveCriticalSection(&m_CriticalSection);
}

int client_manager::GenerateClientCode(void) {
	static int IDSeed = rand() % 100;
	return IDSeed++;
}